import { useRef, useCallback, useEffect } from 'react'
/**
 * 请求锁
 * 默认锁定时间为1秒，请求回来后立刻解锁
 * atLeast：至少被锁定 duration 时间
 */
function useLock<P extends any[] = any[], V extends any = any>(
	fn: (...args: P) => Promise<V>,
	duration: number = 3000,
	atLeast: boolean = false
) {
	const lockRef = useRef(false)
	const countRef = useRef(0)
	const timer = useRef<NodeJS.Timeout | null>(null)
	useEffect(() => {
		return () => {
			timer.current && clearTimeout(timer.current)
		}
	}, [])
	return useCallback(
		async (...args: P) => {
			if (lockRef.current) return
			lockRef.current = true
			if (duration) {
				timer.current && clearTimeout(timer.current)
				timer.current = setTimeout(() => {
					if (atLeast && countRef.current < 1) {
						countRef.current = countRef.current + 1
					} else {
						countRef.current = 0
						lockRef.current = false
					}
				}, duration)
			}
			try {
				const ret = await fn(...args)
				if (atLeast && countRef.current < 1) {
					countRef.current = countRef.current + 1
				} else {
					countRef.current = 0
					lockRef.current = false
				}
				return ret
			} catch (e) {
				if (atLeast && countRef.current < 1) {
					countRef.current = countRef.current + 1
				} else {
					countRef.current = 0
					lockRef.current = false
				}
				throw e
			}
		},
		[fn]
	)
}
export default useLock
